'use strict';

const Service = require('egg').Service;

/**
 * 投稿服务类
 * 处理投稿相关的数据库操作和业务逻辑
 */
class ContributionService extends Service {
  /**
   * 获取投稿列表
   * 支持多条件筛选和分页查询
   * @param {Object} params - 查询参数
   * @param {number} [params.page=1] - 页码
   * @param {number} [params.page_size=10] - 每页条数
   * @param {string} [params.title] - 标题关键字
   * @param {string} [params.author] - 作者姓名，匹配任意作者
   * @param {number} [params.project_group_id] - 项目组ID
   * @param {number} [params.approved_status] - 审核状态：0-未审核，1-已审核，2-未采用
   * @param {number} [params.is_scored] - 打分状态：0-未打分，1-已打分
   * @param {string} [params.start_date] - 开始日期，格式：YYYY-MM-DD
   * @param {string} [params.end_date] - 结束日期，格式：YYYY-MM-DD
   * @returns {Promise<Object>} 包含列表和分页信息的对象
   */
  async findAll(params) {
    const { 
      page = 1, 
      page_size = 10, 
      title, 
      author, 
      project_group_id, 
      approved_status,
      is_scored,
      start_date,
      end_date 
    } = params;
    
    // 建 WHERE 条件
    let conditions = ['c.isDeleted = 0'];
    const queryParams = [];
    
    if (title) {
      conditions.push('c.title LIKE ?');
      queryParams.push(`%${title}%`);
    }
    
    if (author) {
      conditions.push(`(
        p1.person_name LIKE ? OR 
        p2.person_name LIKE ? OR 
        p3.person_name LIKE ?
      )`);
      queryParams.push(`%${author}%`, `%${author}%`, `%${author}%`);
    }
    
    if (project_group_id) {
      conditions.push('c.project_group_id = ?');
      queryParams.push(project_group_id);
    }
    
    if (approved_status !== undefined) {
      conditions.push('c.approved_status = ?');
      queryParams.push(approved_status);
    }

    if (is_scored !== undefined) {
      if(is_scored === 0) {
        conditions.push('c.score IS NULL');
      } else if (is_scored === 1) {
        conditions.push('c.score IS NOT NULL');
      }
    }

    // 添加时间范围条件
    if (start_date) {
      conditions.push('c.created_at >= ?');
      queryParams.push(`${start_date} 00:00:00`);
    }

    if (end_date) {
      conditions.push('c.created_at <= ?');
      queryParams.push(`${end_date} 23:59:59`);
    }
    
    // 计算总数
    const countSql = `
      SELECT COUNT(*) as total 
      FROM tb_contribution c
      LEFT JOIN tb_person p1 ON c.author1 = p1.person_id
      LEFT JOIN tb_person p2 ON c.author2 = p2.person_id
      LEFT JOIN tb_person p3 ON c.author3 = p3.person_id
      WHERE ${conditions.join(' AND ')}
    `;
    const totalResult = await this.app.mysql.query(countSql, queryParams);
    const total = totalResult[0].total;
    
    // 查询数据
    const offset = (page - 1) * page_size;
    const sql = `
      SELECT c.*, 
        p1.person_name as author1_name,
        p2.person_name as author2_name,
        p3.person_name as author3_name,
        d1.department_name as author1_department_name,
        d2.department_name as author2_department_name,
        d3.department_name as author3_department_name,
        pg.project_group_name,
        sp.person_name as scoring_person_name
      FROM tb_contribution c
      LEFT JOIN tb_person p1 ON c.author1 = p1.person_id
      LEFT JOIN tb_person p2 ON c.author2 = p2.person_id
      LEFT JOIN tb_person p3 ON c.author3 = p3.person_id
      LEFT JOIN tb_department d1 ON c.author1_department_id = d1.department_id
      LEFT JOIN tb_department d2 ON c.author2_department_id = d2.department_id
      LEFT JOIN tb_department d3 ON c.author3_department_id = d3.department_id
      LEFT JOIN tb_project_group pg ON c.project_group_id = pg.project_group_id
      LEFT JOIN tb_person sp ON c.scoring_person_id = sp.person_id
      WHERE ${conditions.join(' AND ')}
      ORDER BY c.submission_date DESC
      LIMIT ? OFFSET ?
    `;
    
    const result = await this.app.mysql.query(sql, [...queryParams, page_size, offset]);
    
    return {
      list: result,
      pagination: {
        total,
        page: parseInt(page),
        page_size: parseInt(page_size),
        total_pages: Math.ceil(total / page_size)
      }
    };
  }

  /**
   * 根据ID获取投稿详情
   * 包含作者和部门的详细信息
   * @param {number} id - 投稿ID
   * @returns {Promise<Object|null>} 投稿详情，不存在时返回null
   */
  async findById(id) {
    const sql = `
      SELECT c.*, 
        p1.person_name as author1_name,
        p2.person_name as author2_name,
        p3.person_name as author3_name,
        d1.department_name as author1_department_name,
        d2.department_name as author2_department_name,
        d3.department_name as author3_department_name,
        pg.project_group_name,
        sp.person_name as scoring_person_name
      FROM tb_contribution c
      LEFT JOIN tb_person p1 ON c.author1 = p1.person_id
      LEFT JOIN tb_person p2 ON c.author2 = p2.person_id
      LEFT JOIN tb_person p3 ON c.author3 = p3.person_id
      LEFT JOIN tb_department d1 ON c.author1_department_id = d1.department_id
      LEFT JOIN tb_department d2 ON c.author2_department_id = d2.department_id
      LEFT JOIN tb_department d3 ON c.author3_department_id = d3.department_id
      LEFT JOIN tb_project_group pg ON c.project_group_id = pg.project_group_id
      LEFT JOIN tb_person sp ON c.scoring_person_id = sp.person_id
      WHERE c.contribution_id = ? AND c.isDeleted = 0
    `;
    const result = await this.app.mysql.query(sql, [id]);
    return result[0];
  }

  /**
   * 创建新投稿
   * 自动获取作者的部门信息并计算作者人数
   * @param {Object} data - 投稿数据
   * @param {string} data.title - 标题
   * @param {number} data.author1 - 作者1 ID
   * @param {number} [data.author2] - 作者2 ID
   * @param {number} [data.author3] - 作者3 ID
   * @param {string} [data.remarks] - 备注
   * @param {string} [data.video_file_path] - 视频文件路径
   * @param {number} [data.project_group_id] - 项目组ID
   * @returns {Promise<Object|{error: string}>} 创建的投稿信息，或错误信息
   */
  async create(data) {
    // 获取作者1的部门ID
    const author1 = await this.ctx.service.person.findById(data.author1);
    if (!author1) {
      return { error: 'author1_not_found' };
    }
    data.author1_department_id = author1.department_id;

    // 如果有作者2，获取其部门ID
    if (data.author2) {
      const author2 = await this.ctx.service.person.findById(data.author2);
      if (!author2) {
        return { error: 'author2_not_found' };
      }
      data.author2_department_id = author2.department_id;
    }

    // 如果有作者3，获取其部门ID
    if (data.author3) {
      const author3 = await this.ctx.service.person.findById(data.author3);
      if (!author3) {
        return { error: 'author3_not_found' };
      }
      data.author3_department_id = author3.department_id;
    }

    // 计算作者人数
    data.author_num = 1 + (data.author2 ? 1 : 0) + (data.author3 ? 1 : 0);
    
    // 设置创建时间和提交时间为当前时间
    data.created_at = this.app.mysql.literals.now;
    data.submission_date = this.app.mysql.literals.now;
    data.isDeleted = 0;

    const result = await this.app.mysql.insert('tb_contribution', data);
    return await this.findById(result.insertId);
  }

  /**
   * 更新投稿信息
   * 自动更新作者的部门信息和作者人数
   * @param {number} id - 投稿ID
   * @param {Object} data - 更新数据
   * @param {string} [data.title] - 标题
   * @param {number} [data.author1] - 作者1 ID
   * @param {number} [data.author2] - 作者2 ID
   * @param {number} [data.author3] - 作者3 ID
   * @param {string} [data.remarks] - 备注
   * @param {string} [data.video_file_path] - 视频文件路径
   * @param {number} [data.project_group_id] - 项目组ID
   * @param {number} [data.approved_status] - 审核状态
   * @param {number} [data.score] - 分数
   * @param {number} [data.extra_score] - 额外加分
   * @param {number} [data.tiktok_likes] - 抖音点赞量
   * @param {number} [data.channels_views] - 视频号播放量
   * @param {number} [data.channels_likes] - 视频号点赞量
   * @returns {Promise<Object|{error: string}|null>} 更新后的投稿信息，不存在返回null，作者不存在返回错误信息
   */
  async update(id, data) {
    // 先检查记录是否存在
    const contribution = await this.findById(id);
    if (!contribution) {
      return null;
    }

    // 如果更新了作者，需要更新对应的部门ID
    if (data.author1) {
      const author1 = await this.ctx.service.person.findById(data.author1);
      if (!author1) {
        return { error: 'author1_not_found' };
      }
      data.author1_department_id = author1.department_id;
    }

    if (data.author2) {
      const author2 = await this.ctx.service.person.findById(data.author2);
      if (!author2) {
        return { error: 'author2_not_found' };
      }
      data.author2_department_id = author2.department_id;
    }

    if (data.author3) {
      const author3 = await this.ctx.service.person.findById(data.author3);
      if (!author3) {
        return { error: 'author3_not_found' };
      }
      data.author3_department_id = author3.department_id;
    }

    // 更新作者人数
    if (data.author1 || data.author2 || data.author3) {
      data.author_num = 1 + 
        ((data.author2 || contribution.author2) ? 1 : 0) + 
        ((data.author3 || contribution.author3) ? 1 : 0);
    }

    await this.app.mysql.update('tb_contribution', {
      ...data,
    }, {
      where: { contribution_id: id, isDeleted: 0 }
    });
    
    return await this.findById(id);
  }

  /**
   * 软删除投稿
   * @param {number} id - 投稿ID
   * @returns {Promise<Object|null>} 删除的投稿信息，不存在时返回null
   */
  async delete(id) {
    // 先检查记录是否存在
    const contribution = await this.findById(id);
    if (!contribution) {
      return null;
    }

    // 执行软删除
    await this.app.mysql.update('tb_contribution', {
      isDeleted: 1,
    }, {
      where: { contribution_id: id }
    });

    return contribution;
  }

  /**
   * 审核投稿
   * 只能审核未审核的投稿，且只能审核一次
   * @param {number} id - 投稿ID
   * @param {number} approvedStatus - 审核状态：1-已审核，2-未采用
   * @param {number} approvedRemark - 审核信息
   * @param {number} approvedPersonId - 审核人ID
   * @param {string} approvedPersonName - 审核人姓名
   * @param {string} title - 标题
   * @returns {Promise<Object|{error: string}>} 审核后的投稿信息，或错误信息
   */
  async approve(id, approvedStatus, approvedRemark, approvedPersonId, approvedPersonName,title) {
    // 先检查记录是否存在且未删除
    const contribution = await this.findById(id);
    if (!contribution) {
      return { error: 'not_found' };
    }

    // 检查是否已经审核过
    if (contribution.approved_status !== 0) {
      return { error: 'already_approved' };
    }

    // 执行审核更新
    await this.app.mysql.update('tb_contribution', {
      approved_status: approvedStatus,
      approved_remark: approvedRemark,
      approved_person_id: approvedPersonId,
      approved_person_name: approvedPersonName,
      title
    }, {
      where: { contribution_id: id, isDeleted: 0, approved_status: 0 }  // 只能更新未审核的记录
    });
    
    // 返回更新后的记录
    return await this.findById(id);
  }

  /**
   * 投稿打分
   * 根据启用的规则组计算各作者得分
   * @param {number} id - 投稿ID
   * @param {number} score - 分数
   * @param {number} scoringPersonId - 打分人ID
   * @returns {Promise<Object|{error: string}>} 打分后的投稿信息，或错误信息
   * @throws {Error} 当规则组未启用或权重配置错误时抛出异常
   */
  async score(id, score, scoringPersonId) {
    // 先检查记是否存在且未删除
    const contribution = await this.findById(id);
    if (!contribution) {
      return { error: 'not_found' };
    }

    // 检查是否已审核通过
    if (contribution.approved_status !== 1) {
      return { error: 'not_approved' };
    }

    // 获取启用的规则组
    const enabledRules = await this.ctx.service.scoringRule.getEnabledGroup();
    if (!enabledRules || enabledRules.length === 0) {
      return { error: 'no_enabled_rule' };
    }

    // 根据作者人数找到对应的规则
    const rule = enabledRules.find(r => r.num_authors === contribution.author_num);
    if (!rule) {
      return { error: 'no_matching_rule' };
    }

    // 验证权重之和是否等于1
    const totalWeight = rule.author1_weight + 
      (rule.author2_weight || 0) + 
      (rule.author3_weight || 0);
    
    if (Math.abs(totalWeight - 1) > 0.000001) { // 使用小数点精度比较
      return { error: 'invalid_weights' };
    }

    const ruleGroupId = rule.rule_group;

    // 计算各作者得分（修改这部分）
    const author1Score = Number((score * rule.author1_weight).toFixed(2));
    const author2Score = contribution.author2 ? 
      Number((score * rule.author2_weight).toFixed(2)) : null;
    const author3Score = contribution.author3 ? 
      Number((score * rule.author3_weight).toFixed(2)) : null;

    // 执行更新
    await this.app.mysql.update('tb_contribution', {
      score,
      scoring_person_id: scoringPersonId,
      scoring_rule_group_id: ruleGroupId,
      author1_score: author1Score,
      author2_score: author2Score,
      author3_score: author3Score,
    }, {
      where: { contribution_id: id, isDeleted: 0 }
    });
    
    // 返回更新后的记录
    return await this.findById(id);
  }
}

module.exports = ContributionService; 